home *** CD-ROM | disk | FTP | other *** search
- TITLE 'CRC.ASM Version 6.5 for MSDOS'
- ; by Howard Vigorita, NYACC CP/M SIG
- ; upload comments, etc. to: (718) 539-3338 (BBS)
- ;
- ; A file CRC checking and generating utility for CP/M-86,
- ; MP/M-86 and Concurrent PCDOS, now available for MSDOS.
- ;
- ; Derived from the Bill Bolton's CP/M 86 version.
- ;
- ; This is a companion utility to CRCBUILD which creates
- ;-CATALOG files. This utility uses the -CATALOG file as an
- ;interactive look up table and displays *MATCH* on your screen
- ;next to each line whose embedded CRC agrees with disk contents.
- ;
- ; This utility will optionally create an output file on
- ;the default drive, listing the CRC's of all files checked in a
- ;single session.
- ;
- ;
- ;COMMANDS:
- ;
- ; CRC [drive:]<filename.filetype> [F]
- ;
- ; Examples:
- ;
- ; CRC Will attempt to find CRCKLIST.???,
- ; or CRCKFILE.??? or -CATALOG.???
- ; and try to match recorded CRC values
- ; in that file with values calculated
- ; on the fly for files on the disk.
- ;
- ; CRC MYFILE.ASM Check only MYFILE.ASM
- ;
- ; CRC B:*.ASM Check all .ASM files ON B: drive
- ;
- ; CRC *.* F Check all files, writing output to a file
- ;
- ;
- ;
- ;SPECIAL MSDOS NOTE
- ;
- ; This CRCK version fixes a bug in some MSDOS versions whereby
- ;partial sectors of files were not being processed. Such versions
- ;generate "00 00" CRC values for files less than 128 bytes in length
- ;and incorrect values for files not an exact multiple of 128 bytes
- ;long. Use this version of CRC with CRCBUILD version 1.1 which
- ;also fixes this bug.
- ;
- ;
- ;The CYCLIC-REDUNDANCY-CHECK number used is based on the
- ;CCITT standard polynominal:
- ;
- ; X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
- ;
- ;Useful for checking accuracy of file transfers.
- ;More accurate than a simple checksum.
- ;
- ;
- ;CREDITS
- ;
- ; The 8 bit version of the program was originally
- ; conceived by Keith Petersen, W8SDZ, to whom all
- ; glory and honour.
- ;
- ;
- ;VERSION LIST, most recent version first
- ;
- ;03/Nov/85 Altered buffer scheme to accept any size buffer.
- ; CRC algorithm further optimized. Fixed bug in
- ; version 6.4 whereby files between 65409 and 65535
- ; bytes long yielded 00 00 CRC values.
- ; Up to 600% faster than when 128 byte buffer used.
- ; MSDOS version 6.5, Howard Vigorita
- ;
- ;30/Oct/85 High speed version using 32K buffer on the file being CRC'd.
- ; Buffer size variable but must devide evenly into 64K.
- ; Up to 500% faster than when 128 byte buffer used.
- ; CRC algorithm optimized.
- ; MSDOS version 6.4, Howard Vigorita
- ;
- ;20/Oct/85 Converted to MSDOS for assembly by MASM
- ; MSDOS version 6.3, Howard Vigorita
- ;
- ;30/Oct/84 Added CLOSE to file read routines, as Concurrent DOS
- ; was reporting "Too many Files Open" error when CRCing
- ; disks with lots of directory entries. Made the same
- ; changes to the 8 bit versions.
- ; CP/M-86/Concurrent version 6.4. Bill Bolton
- ;
- ;10/Oct/84 Fixed CP/M-86 version to also work with Concurrent PCDOS,
- ; and MP/M-86. The "?" in the OPEN function calls was
- ; upsetting them. CP/M-86/Concurrent version 6.3. Bill Bolton
- ;
- ;09/Oct/84 XLT86 translation of 8 bit source code version, massaged
- ; by hand to make it assemble with ASM86 for CP/M-86.
- ; CP/M-86 version 6.2. Bill Bolton
- ;
- ;07/Oct/84 Tightened 8 bit disassembly considerably and moved all
- ; the data together preparatory to XLT86ing for CP/M-86.
- ; CP/M-80 version 6.2. Bill Bolton
- ;
- ;04/Oct/84 Disassembled CRC version 5.0 as distributed for some years
- ; on SIG/M disks, but no source has even been available from
- ; SIG/M. This version checks the -CATALOG files built with
- ; CRCBUILD as well as CRCKLIST and CRCKFILE. Obviously used
- ; SEQIO macros for much of the file I/O but as the aim is
- ; translation to CP/M-86 I left the macros expanded. Lifted
- ; recognisable bits of code (like MFNAME) from other sources
- ; to get comments. Version number 6.1.
- ; Bill Bolton, Software Tools RCPM, Brisbane Australia
- ;
- ;-------------------------------------------------------------------
-
- ; conditional assembly switches
- ; -----------------------------
- true equ 0FFh
- false equ 0
-
- ; switch to supress "no parse" error messages
- ; set to 'false' to prevent screen clutter when using
- ; a -CATALOG file with a multi-line footer
- ;
- no_parse_msg equ false
-
- ; equates
- ; -------
- dos equ 33 ; MSDOS entry point
-
- rdcon equ 1 ; console input
- wrcon equ 2 ; console output
- dircon equ 6 ; direct console I/O
- print equ 9 ; display string
- cstat equ 11 ; console status
- open equ 15 ; file open
- close equ 16 ; file close
- srchf equ 17 ; search for first
- srchn equ 18 ; search for next
- delete equ 19 ; delete file
- read equ 20 ; read file
- write equ 21 ; write file
- make equ 22 ; create file
- rename equ 23 ; rename existing file
- setdta equ 26 ; set transfer address
- setiv equ 25h ; set interrupt vector
- makstr equ 3Ch ; make stream handle
- opnstr equ 3Dh ; open a file stream
- clostr equ 3Eh ; close file stream
- redstr equ 3Fh ; read from a stream
- wrtstr equ 40h ; write to a stream
- deldir equ 41h ; delete a directory entry
- trmproc equ 4Ch ; terminate process
-
- tab equ 09H ;ASCII modulo 8 tab
- lf equ 0AH ;ASCII line feed
- cr equ 0DH ;ASCII carriage returnq
- eof equ 1AH ;CP/M end of file marker
-
- bufsize equ 80H ;File buffers
- bufsizl equ 200h ; large file buffer
- dtamax equ 1024*54 ; max size of dynamic dta
-
- secsizs equ 128 ; disk sector size
-
- ; base page program segment prefix
- ; --------------------------------
- ;
- basepg SEGMENT AT 0
-
- ; base page file control block
- ;
- ORG 5Ch
- dfcb db 12 dup (?)
- dfcbext db 4 dup (?)
- dfcb2 db 16 dup (?)
- dfcbrno db (?)
-
- ; default disk transfer area
- ;
- ORG 80h
- ddta db 128 dup (?)
-
- basepg ENDS
-
-
-
- ; program data storage area
- ; -------------------------
- ;
- data SEGMENT PARA MEMORY
-
-
- FIRST_TRY db 'CRCKFILE???',0
-
- SIGNON db 'MSDOS high speed CRC Ver 6.5, 3/Nov/85, Howard Vigorita',cr,lf
- db 'CTL-S pauses, CTL-C aborts',cr,lf,cr,lf,0
-
- SRCH_LIST db 'Searching for "CRCKLIST" file ',0
-
- SRCH_FILE db 'Now searching for "CRCKFILE" file',0
-
- SRCH_CAT db 'Now searching for "-CATALOG" file',0
-
- NOFILECRC db tab
- db 'Not found$'
-
- CHECKING db tab,'Checking with file: ',0
-
- NOFIND db '*No CRC Files found*',0
-
- CANTPARSE db 'Can not parse string',cr,lf,0
-
- DASH db ' - ',0
-
- NOFIND2 db ' File not found',cr,lf,0
-
- MATCHMSG db ' *Match*',cr,lf,0
-
- ISWAS db ' <-- is, was --> ',0
-
- NOTSPACE db 'Not a space between CRC values',0
-
- DISKFULL db cr,lf
- db 'Disk full: CRCKLIST$'
-
- makerr db cr,lf
- db "Can't make temporary file: CRCKLIST$"
-
- dtasmall db cr,lf
- db 'Disk transfer area too small: CRCKLIST$'
-
- NOFIND3 db ' ++File not found++$'
-
- FINITO db cr,lf
- db 'DONE$'
-
- newln db cr,lf
- ARROW db '--> FILE: '
- FNAME db 'XXXXXXXX.XXX'
- EQUALS db tab,tab,'CRC = ',0
-
- BADopen db ' ++Open failed++',0
-
- READERR db tab,tab
- ; db ' ++File read error++'
- db cr,lf,0
-
- abtext db cr,lf
- db "Can't close CRC file$"
-
- ABORT db cr,lf,cr,lf
- db '++ABORTED++$'
-
- CRCMATCH db 'Quantity of file CRC that matched - ',0
-
- CRCNOMATCH db 'Quantity of file CRC that did not match - ',0
-
- BADPARSE db 'Quantity of lines failed parse test - ',0
-
- QTYNOFIND db 'Quantity of file(s) not found - ',0
-
- FCBCRCFILE db 0,'CRCKLIST???',0
- db 0,'CRCKFILE???',0
- db 11 dup (?)
- CRCFILELEN dw bufsize
- CRCFILEPTR db 2 dup (?)
-
- crcouth dw (?)
- crcoutz db 'CRCKLIST.$$$',0
- zstring db 'A:????????.???',0
- infileh dw (?)
-
- CATALOG db '-CATALOG???',0
-
-
- POINTER db 2 dup (?)
- MATCHNO db (?)
- NOMATCH db (?)
- FAILED db (?)
- FILES db (?)
- FFLAG db (?)
- REM db 2 dup (?)
- OLDCRC db 2 dup (?)
- MESS db (?)
- MFFLG1 db 1
- CRCENTRY dw 1
- MATCHFLG db (?)
- CURSOR db 2 dup (?)
-
-
- dtabws dw (?) ; dta bytes in whole sector
- dtabps dw (?) ; dta bytes in partial sector
- crcbuf db (?) ; buffer used by stream write
-
- FCBFINAL db 0,'CRCKLISTCRC',0 ; continued in dynamic area
-
- ; start of dynamic storage area - this storage area is not allocated,
- ; the addresses are merely defined with daisy chained equates so that
- ; no space is taken up in the EXE file. This technique depends on
- ; the DATA segment being loaded higher than any other segment.
- ;
- dsa equ $
- FCBFINAL_cont equ dsa ; db 24 dup (?) must be 1st
- buffer equ FCBFINAL_cont+24 ; db 80 dup (?)
- fcb equ buffer+80 ; db 12 dup (?)
- fcbext equ fcb+12 ; db 4 dup (?)
- fcb2 equ fcbext+4 ; db 16 dup (?)
- fcbrno equ fcb2+16 ; db 5 dup (?)
- MFREQ equ fcbrno+5 ; db 12 dup (?)
- MFCUR equ mfreq+12 ; db 12 dup (?)
- crcfilebuf equ mfcur+12 ; db bufsizl dup (?)
- dta equ crcfilebuf+bufsizl ; open ended - must be last
-
- data ENDS
-
-
-
-
- ; program starts here
- ;--------------------
- ;
- code SEGMENT PARA PUBLIC
- assume CS:code ; this segment
- assume DS:basepg ; DS points at base page for now
- assume SS:a_stack ; stack segment
-
- crck:
-
- mov AX,data ; init extra segment to point
- mov ES,AX ; to our program data area
- assume ES:data
-
- ; copy base page to prog data area
- ;
- mov SI,offset dfcb ; base page fcb to source index
- mov DI,offset fcb ; prog data area fcb to dest index
- mov CX,37 ; # of bytes to copy
- rep movsb ; block copy
- mov SI,offset ddta ; base page DMA to source index
- mov DI,offset dta ; prog data area DMA to dest index
- mov CX,40h ; # of words to copy
- rep movsw ; block copy
-
-
- ; point DS register at program data area
- ;
- push ES
- pop DS
- assume DS:data
-
- ; intercept the ctl-C interrupt vector
- ;
- mov AH,setiv
- mov AL,23h
- mov DX, offset abext2 ; point it to our routine
- push DS ; save program data segment
- push CS ; put code segment into
- pop DS ; DS for interrupt handler
- int dos
- pop DS ; restore our data segment
-
- ; turn on extended ctl-c detection
- ;
- mov AH,33h
- mov AL,1
- mov DL,1
- int dos
-
- START:
- call CRLF ; turn up a new line
- mov DX,offset SIGNON ; Tell them who we are
- call DISPLAY
- mov AL,Byte Ptr FCB+1 ;Point to file name
- cmp AL,' ' ;Is it there?
- jz CONTINUE
- jmp FILE_OUT_CHECK ;Yes
-
- CONTINUE:
-
- mov DX,offset SRCH_LIST ;Searching for CRCKLIST.??? file
- call DISPLAY
- call OPENCRCFILE
- jz PROCESSIT
- mov DX,offset SRCH_FILE
- call DISPLAY ;Searching for CRCKFILE.??? file
- mov SI,Offset FIRST_TRY
- mov DI,Offset FCBCRCFILE+1
- mov CX,11
- rep movsb
- call OPENCRCFILE
- jz PROCESSIT
- jmp CATCHECK
-
- PROCESSIT:
- call FINDCRC
- jz PROCESS2
- jmp ABEXT2
-
- PROCESS2:
- mov DX,offset ARROW
- mov BX,offset buffer
- mov CX,11
- call COMPARE
- jnz NONSENSE
- call ISNAME
- jnz NONSENSE
- mov DX,offset EQUALS
- mov CL,31
- call COMPARE
- jnz NONSENSE
- call STORECRC
- jnz NONSENSE
- mov BX,offset buffer+11
- call SHOWNAME
- jmp short PROCESSIT
-
- NONSENSE:
- call NOPARSE
- jmp short PROCESSIT
-
- ; -CATALOG and CRCKLIST read routine
- ;
- READFILE:
- mov BX,word ptr crcfileptr ; get the buffer pointer
- cmp BX,offset crcfilebuf+bufsizl ; see if points to end
- jnz readabyte ; if not, go get a byte
- mov BX,offset crcfilebuf ; else, load buffer address
- mov Word Ptr CRCFILEPTR,BX ; reset buffer pointer to it
- READLOOP:
- mov DX,BX ; get buffer address into DX
- mov AH,setdta ; point dta at it
- int dos
- mov DX,offset FCBCRCFILE ; get fcb address
- mov AH,read ; read a sector
- int dos
- or AL,AL ; see if read a whole sector
- jz rl_2 ; if so, continue
- cmp AL,3 ; see if read a partial sector
- jnz LASTread ; if not, must be eof or error
- rl_2:
- add BX,secsizs ; move buffer ptr by a sector
- cmp BX,offset crcfilebuf+bufsizl ; see if BX points to end
- jnz READLOOP
- jmp short resetdma
-
- LASTREAD:
- mov Word Ptr CRCFILELEN,BX ; make sure file length correct
- resetdma:
- mov DX,offset dta ; point back to dta of data file
- mov AH,setdta
- int dos
- mov BX,Word Ptr CRCFILEPTR ; get buffer pointer back
- READABYTE:
- cmp BX,word ptr crcfilelen
- mov AL,eof
- jnz READBYTE1
- ret
- READBYTE1:
- mov AL,byte ptr [BX]
- inc BX
- mov word ptr crcfileptr, BX
- ret
-
- OPENCRCFILE:
- xor AL,AL
- mov Byte Ptr FCBCRCFILE+12,AL
- mov Byte Ptr FCBCRCFILE+32,AL
- mov BX,offset crcfilebuf+bufsizl ; point to end of buffer
- mov word ptr crcfileptr,BX ; init buffer ptr to it
- mov word ptr crcfilelen,BX ; and also the file length
- mov SI,offset FCBCRCFILE ;CCP/M doesn't like "?" in
- mov DI,offset FCB ; OPEN function calls, so
- mov CX,6 ; since we already have
- rep movsw ; MFNAME in the code, use it to
- call MFNAME ; get a definitive filename
- jb OPENFAIL ; to attempt an open. Only
- mov SI,offset FCB ; the first matching name is
- mov DI,offset FCBCRCFILE ; tried for an open, but this is all
- mov CX,6 ; the orginal code achieved anyway.
- rep movsw
- mov AH,OPEN
- mov DX,offset FCBCRCFILE
- int dos
- inc AL
- jnz FILEMATCH
- OPENFAIL:
- mov AH,print
- mov DX,offset NOFILECRC
- int dos
- jmp FILERR
-
- FILEMATCH:
- mov SI,offset FCBCRCFILE+1
- mov DI,offset buffer
- mov CX,4
- rep movsw
- mov AL,'.'
- mov byte ptr [DI],AL
- inc DI
- mov CX,3
- rep movsb
- xor AL,AL
- mov byte ptr [DI],AL
- mov DX,offset CHECKING ;Show which file we are checking
- call DISPLAY
- mov BX,offset buffer
- MATCHLOOP:
- mov AL,byte ptr [BX]
- or AL,AL
- jz MATCHINIT
- call TYPER
- inc BX
- jmp short MATCHLOOP
-
- MATCHINIT:
- call CRLF
- call CRLF
- xor AL,AL
- mov Byte Ptr MATCHNO,AL
- mov Byte Ptr NOMATCH,AL
- mov Byte Ptr FAILED,AL
- mov Byte Ptr FILES,AL
- ret
-
- FINDCRC:
- mov BX,offset buffer
- mov AL,0
- mov Byte Ptr CURSOR,AL ;Reset cursor counter to start of line
- FINDCRC1:
- push BX
- call READFILE
- pop BX
- cmp AL,eof
- jnz FINDCRC2
- mov AL,Byte Ptr CURSOR
- or AL,AL
- jnz FINDDONE
- mov AL,Byte Ptr CRCENTRY
- or AL,AL
- jnz FINDCRC1A
- jmp DONEIT
-
- FINDCRC1A:
- mov DX,offset NOFIND ;File not found
- call DISPLAY
- mov AL,eof
- or AL,AL
- ret
-
- FINDCRC2:
- and AL,07FH ;Make sure its ASCII
- cmp AL,cr ;End of line?
- jz ENDOFLINE ;Yes
- cmp AL,lf ;End of line?
- jz ENDOFLINE ;Yes
- mov byte ptr [BX],AL ;No
- inc BX
- mov AL,Byte Ptr CURSOR ;Bump cursor pointer
- inc AL
- mov Byte Ptr CURSOR,AL
- cmp AL,80 ;End of line?
- jb FINDCRC1 ;No
- ENDOFLINE:
- mov AL,Byte Ptr CURSOR
- or AL,AL
- jz FINDCRC
- FINDDONE:
- mov byte ptr [BX],0
- xor AL,AL
- ret
-
- NOPARSE:
- if no_parse_msg
- mov DX,offset CANTPARSE ;Cant parse string
- call DISPLAY
- endif
-
- mov BX,offset buffer
- PARSELOOP:
- mov AL,byte ptr [BX]
- or AL,AL
- jz SHOWERR
- call TYPER
- inc BX
- jmp short PARSELOOP
- ;
- SHOWERR:
- if no_parse_msg
- call CRLF
- endif
-
- mov BX,offset buffer
- inc CH
- dec CH
- jz SHOWERR3
- SHOWERR1:
- mov AL,tab
- cmp AL,byte ptr [BX]
- jz SHOWERR2
- mov byte ptr [BX],' '
- SHOWERR2:
- inc BX
- dec CH
- jnz SHOWERR1
- SHOWERR3:
- mov byte ptr [BX],'^'
- inc BX
- mov byte ptr [BX],0
- mov BX,offset buffer
- SHOWERR4:
- mov AL,byte ptr [BX]
- or AL,AL
- jz RECORDERR
-
- if no_parse_msg
- call TYPER
- endif
-
- inc BX
- jmp short SHOWERR4
-
- RECORDERR:
- mov BX,offset FAILED
- inc byte ptr [BX]
- call CRLF
- ret
- ;
- COMPARE:
- mov SI,DX
- mov AL,byte ptr [SI]
- cmp AL,byte ptr [BX]
- jz COMPARE1
- ret
- ;
- COMPARE1:
- inc BX
- inc DX
- inc CH
- mov AL,CH
- cmp AL,CL
- jnz COMPARE2
- ret
- ;
- COMPARE2:
- jmp short COMPARE
- ;
- SHOWNAME:
- mov SI,BX
- mov DI,offset fcb+1
- mov CX,4
- rep movsw
- inc SI
- mov CX,3
- mov DI,offset fcb+9
- rep movsb
- xor AL,AL
- mov byte ptr [SI],AL
- SHOWLOOP:
- mov AL,byte ptr [BX]
- or AL,AL
- jz SHOWDONE
- call TYPER
- inc BX
- jmp short SHOWLOOP
- ;
- SHOWDONE:
- mov AL,1
- mov Byte Ptr MFFLG1,AL
- mov DX,offset DASH ;Display delimiter
- call DISPLAY
- call MFNAME
- jnb TRYMATCH
- mov DX,offset NOFIND2
- call DISPLAY
- mov BX,offset FILES
- inc byte ptr [BX]
- xor AL,AL
- inc AL
- ret
-
- TRYMATCH:
- mov AL,1
- mov Byte Ptr MATCHFLG,AL ;We found some filenames to check
- call OPENIT
- jz TRYMATCH1
- ret
-
- TRYMATCH1:
- mov AL,Byte Ptr OLDCRC+1
- mov CH,AL
- mov AL,Byte Ptr REM
- cmp AL,CH
- jnz MISMATCH
- mov AL,Byte Ptr OLDCRC
- mov CH,AL
- mov AL,Byte Ptr REM+1
- cmp AL,CH
- jnz MISMATCH
- mov DX,offset MATCHMSG ; *Match*
- call DISPLAY
- xor AL,AL
- mov Byte Ptr CRCENTRY,AL
- mov BX,offset MATCHNO
- inc byte ptr [BX]
- xor AL,AL
- ret
-
- MISMATCH:
- mov DX,offset ISWAS ; <--is, was -->
- call DISPLAY
- mov AL,Byte Ptr OLDCRC
- call HEXO
- mov AL,' '
- call TYPER
- mov AL,Byte Ptr OLDCRC+1
- call HEXO
- call CRLF
- xor AL,AL
- mov Byte Ptr CRCENTRY,AL
- mov BX,offset NOMATCH
- inc byte ptr [BX]
- xor AL,AL
- inc AL
- ret
-
- STORECRC:
- call HEXBIN
- jz STORECRC0
- ret
-
- STORECRC0:
- mov Byte Ptr OLDCRC,AL
- mov AL,byte ptr [BX]
- inc BX
- cmp AL,' '
- jz STORECRC1
- mov DX,offset NOTSPACE ;No space between CRC values
- call DISPLAY
- xor AL,AL
- inc AL
- ret
-
- STORECRC1:
- call HEXBIN
- jz STORECRC2
- ret
-
- STORECRC2:
- mov Byte Ptr OLDCRC+1,AL
- mov CH,AL
- xor AL,AL
- ret
-
- CATCHECK:
- mov DX,offset SRCH_CAT ;Searching -CATALOG file
- call DISPLAY
- mov SI,offset CATALOG
- mov DI,offset FCBCRCFILE+1
- mov CX,11
- rep movsb
- call OPENCRCFILE
- jz PARSELINE
- jmp ABEXT2
- ;
- PARSELINE:
- call FINDCRC
- jz PARSE2
- jmp ABEXT2
- ;
- PARSE2:
- mov CH,0
- mov BX,offset buffer ;Point to catalog entry
- call THREENUM ;Check for 3 digit volume number
- jnz TRYAGAIN
- mov AL,'.' ;Followed by separator
- cmp AL,byte ptr [BX]
- jnz TRYAGAIN
- lahf
- inc BX
- sahf
- inc CH
- call TWONUM ;Check for 2 digit entry number
- jnz TRYAGAIN
- call ISWHITE ;Skip over white space
- jnz TRYAGAIN
- call ISNAME ;Check for valid file name
- jnz TRYAGAIN
- call ISWHITE ;Skip over white space
- jnz NOGOOD
- call ISNUM ;Check for first digit of filesize
- jnz NOGOOD
- SKIP:
- call ISNUM
- jz SKIP
- cmp AL,'K' ;Filesize ends in K
- jnz NOGOOD
- call ISWHITE ;Skip over white space
- jnz NOGOOD
- call STORECRC ;Now we should be at the CRC
- jnz NOGOOD
- mov BX,Word Ptr POINTER
- call SHOWNAME
- jmp short PARSELINE
- ;
- TRYAGAIN:
- mov AL,Byte Ptr CRCENTRY
- or AL,AL
- jnz PARSELINE
- NOGOOD:
- call NOPARSE
- jmp PARSELINE
- ;
- ISNAME:
- mov Word Ptr POINTER,BX
- call ISALPHA ;Check first character
- jz ISNAME0
- ret
- ;
- ISNAME0:
- mov CL,7 ;7 left in rest of filename
- ISNAME1:
- call ISALPHA
- jz ISNAME2
- cmp AL,' ' ;Maybe padded with spaces?
- jz ISNAME2
- ret
- ;
- ISNAME2:
- dec CL ;Done?
- jnz ISNAME1 ;No
- mov AL,byte ptr [BX] ;Yes
- inc BX
- inc CH
- cmp AL,'.' ;Valid separator?
- jz ISNAME3
- ret
- ;
- ISNAME3:
- mov CL,3 ;3 in filetype
- ISNAME4:
- call ISALPHA
- jz ISNAME5
- cmp AL,' ' ;Padded with spaces
- jz ISNAME5
- ret
- ;
- ISNAME5:
- dec CL ;Done?
- jnz ISNAME4 ;No
- ret ;Yes
- ;
- ISWHITE:
- mov AL,byte ptr [BX]
- cmp AL,' ' ;Space?
- jz WHITELOOP ;Yes, check some more
- cmp AL,tab ;No, maybe a tab?
- jz WHITELOOP
- ret ;No, something else
- ;
- WHITELOOP:
- inc BX ;Point to next char
- inc CH
- mov AL,byte ptr [BX]
- cmp AL,' ' ;Space?
- jz WHITELOOP ;Yes, check some more
- cmp AL,tab ;No, maybe a tab?
- jz WHITELOOP ;Yes, check some more
- cmp AL,AL ;No, something else
- ret
- ;
- THREENUM:
- call TWONUM
- jz THREENUM1
- ret
- ;
- THREENUM1:
- call ISNUM
- jnz THREENUM2
- ret
- ;
- THREENUM2:
- cmp AL,'.'
- jz THREENUM3
- ret
- ;
- THREENUM3:
- dec BX
- dec CH
- cmp AL,AL
- ret
- ;
- TWONUM:
- call ISNUM
- jz ISNUM
- ret
- ;
- ISNUM:
- mov AL,byte ptr [BX]
- inc BX
- inc CH
- cmp AL,'0'
- jb NOTNUM
- cmp AL,'9'+1
- jnb NOTNUM
- cmp AL,AL
- ret
- ;
- NOTNUM:
- cmp AL,'0'
- ret
- ;
- ISALPHA:
- mov AL,byte ptr [BX]
- inc BX
- inc CH
- cmp AL,' '+1
- jb ALPHA1
- cmp AL,07Fh
- jnb ALPHA1
- cmp AL,AL
- ret
-
- ALPHA1:
- cmp AL,'A'
- ret
-
- HEXBIN:
- call MAKEBIN
- jz HEXBIN1
- ret
-
- HEXBIN1:
- ROL AL,1
- ROL AL,1
- ROL AL,1
- ROL AL,1
- mov CL,AL
- call MAKEBIN
- jz HEXBIN2
- ret
-
- HEXBIN2:
- mov CH,AL
- mov AL,CL
- or AL,CH
- cmp AL,AL
- ret
- ;
- MAKEBIN:
- mov AL,byte ptr [BX]
- inc BX
- inc CH
- cmp AL,'0'
- jb MAKEBIN2
- sub AL,'0'
- cmp AL,10
- jb MAKEBIN1
- and AL,1FH
- sub AL,7H
- cmp AL,10
- jb MAKEBIN2
- cmp AL,16
- jnb MAKEBIN2
- MAKEBIN1:
- cmp AL,AL ;Return zero flag not set
- ret
-
- MAKEBIN2:
- or AL,AL ;Return zero flag set
- ret
-
- FILE_OUT_CHECK:
- mov AL,Byte Ptr FCB2+1 ;Point to possible file write command
- mov Byte Ptr FFLAG,AL ;Save as a flag
- cmp AL,'F' ;Is it the correct one?
- jz makecrcfile ;Yes
- jmp AGAIN ;NO
-
- putcrcfile:
- mov byte ptr crcbuf,AL
- mov DX, offset crcbuf
- mov CX,1
- mov BX, word ptr crcouth ; stream # to BX
- mov AH,wrtstr ;write 1 char to -catalog file stream
- int dos
- jnc putcrc_4
- cmp AX,5
- jz putcrc_1
- cmp AX,6
- jz putcrc_2
- ret
- putcrc_1:
- mov DX,offset diskfull
- jmp short putcrc_3
- putcrc_2:
- mov DX,offset dtasmall
- putcrc_3:
- mov AH,print
- int dos
- jmp filerr
- putcrc_4:
- ret
-
- makecrcfile:
- mov DX, offset crcoutz ; z-string of tmp crc output file
- xor CX,CX ; no file attribute
- mov AH,makstr ; make file & stream
- int dos
- mov word ptr crcouth,AX ; save the stream #
- jnc again ; if no error, start file lookup
- mov AH,print ; else print error message
- mov DX,offset makerr
- int dos
- jmp abext2
-
- AGAIN:
- mov Byte Ptr MATCHFLG,0
- call MFNAME
- JNAE AGAIN1
- jmp DOFILECRC
- ;
- AGAIN1:
- mov AL,Byte Ptr MFFLG1
- or AL,AL
- jz DONE
- mov DX,offset NOFIND3
- mov AH,print
- int dos
- jmp ABEXT2
-
- DONE:
- mov AL,Byte Ptr FFLAG ; get outfile open flag
- cmp AL,'F' ; see if outfile open
- jnz doneit ; skip file stuff if not
-
- CLOSEIT:
- call crlf
- mov AL,eof
- call putcrcfile
- mov AH,clostr ; Close stream
- mov BX,word ptr crcouth ; CRCKLIST.$$$ stream number
- int dos
- jnc ERASEIT ; continue if carry not set
- mov AH,print ; else, print error message
- mov DX,offset abtext
- int dos
- jmp filerr
-
- ;Erase any existing CRCKLIST.CRC file
- ;
- ERASEIT:
- mov AH,delete
- mov DX,offset FCBFINAL
- int dos
-
- RENLOOP:
- mov SI,offset crcoutz+9 ; location of '$$$' in z-string
- mov DI,offset fcbcrcfile+9 ; location of fcb1 filetype
- mov CX,3 ; # of bytes
- rep movsb ; block move
- mov SI,offset fcbfinal ; start of CRCFILE.CRC filename
- mov DI,offset fcbcrcfile+16 ; location of fcb2
- mov CX,12 ; # of bytes
- rep movsb ; block move
- mov DX,offset fcbcrcfile ; address of modified fcb
- mov AH,rename ; Rename CRCKLIST.$$$ to CRCKLIST.CRC
- int dos
- DONEIT:
- mov DX,offset FINITO
- jmp SIGNOFF
-
- DOFILECRC:
- mov BX,offset fcb+9 ; point BX at the file type
- call TSTBAD ; test for $$$ filetype
- jnz DOFILECRC0 ; continue if not
- jmp AGAIN ; else get another file name
-
- dofilecrc0:
- cmp byte ptr fcb+1,'-' ; see if filename starts with a dash
- jnz dofilecrc1 ; continue if not
- jmp again ; else skip it
-
- DOFILECRC1:
- mov SI,offset fcb+1 ; copy file name from fcb
- mov DI,offset FNAME ; to display string
- mov CX,4 ; consisting of 8 characters
- rep movsw ; with a block move
- mov SI,offset fcb+9 ; also copy the fcb file type
- mov DI,offset FNAME+9 ; into the display string
- mov CX,3 ; which is 3 characters long
- rep movsb ; with a block move
- mov DX,offset newln ; now display it
- call DISPLAY
- call OPENIT ; open file ref'd by fcb
- jnz DOFILECRC3 ; if 0 not ret'd, bad open
- jmp AGAIN ; else continue
-
- DOFILECRC3:
- jmp ABEXT2
-
- ; before opening the file we're going to do the crck on,
- ; compute optimum record sizes
- openit:
-
- mov BX,word ptr dta+1Dh ; get file size low word to BX
- mov CX,word ptr dta+1Fh ; get file size high word to CX
- add BX,7Fh ; bump to next 128 byte boundary
- adc CX,0 ; add any carry to CX
- and BL,80h ; mask off bottom 7 bits
- mov word ptr dtabps,BX
- mov word ptr dtabws,BX
-
- ; double-word size less than maximum size of dta?
- dwltm: or CX,CX ; BX = 0 ? ( < 64K? )
- jnz dwltmNO ; NO, then max bws & figure bps
- cmp BX,dtamax ; check the low word
- jbe dwltmYES ; YES, set bws to file size
- dwltmNO:
- mov word ptr dtabws,dtamax ; set bytes in whole sector max
- reduce:
- ; compute number of bytes in the final partial record
- sub BX,dtamax ; reduce low word by dtamax
- sbb CX,0 ; & subtract any borrow from BX
-
- ; compare double word to maximum dta size
- or CX,CX ; less than 64K ?
- jnz reduce ; if not, reduce some more
- cmp BX,dtamax ; low word <= dtamax ?
- jnb reduce ; if neither, reduce some more
-
- mov word ptr dtabps,BX ; save partial record size
- jmp short rdinit
-
- dwltmYES:
- mov word ptr dtabws,BX ; set whole sector size to file size
-
- ; initialization to read the file we're doing the crck on
- rdinit:
- ; unparse from file control block into zstring
- mov SI,offset fcb ; filename address in SI
- mov DI,offset zstring ; zstring address in DI
- movsb
- add byte ptr zstring,40h
- inc DI
- mov CX,8 ; # of bytes
- rep movsb
- inc DI ; skip over decimal point
- mov CX,3 ; # of bytes in filetype
- rep movsb ; block move
-
- mov AH,opnstr ; open file stream
- xor AL,AL ; read only mode
- mov DX,offset zstring ; file to open
- int dos
- mov word ptr infileh,AX ; save the input file handle
- jnc rdinit_1 ; if no error, continue
- mov DX,offset BADOPEN ; else, tell operator
- call DISPLAY
- call crlf
- xor AL,AL
- inc AL ; ret NZ for bad open
- ret
-
- ; register usage during read loop as follows:
- ; AH = dos function number & flag holder
- ; AL = target of load byte from buffer
- ; AX = # of bytes to read from the file stream
- ; BX = accumulated CRC remainder & file stream handle
- ; CX = count of # of bytes in buffer
- ; DX = buffer beginning address
- ; SI = pointer to next character in buffer
- ; DI = pointer to end of partial record
- ;
- rdinit_1:
- xor BX,BX ; init crc accumulator to 0
- mov DX,offset dta ; point DX at start of buffer
-
- ; routine to refill the dta
- ;
- filldta:
- mov AH,redstr ; read a record from file
- mov word ptr REM,BX ; save the CRC remainder
- mov BX,word ptr infileh ; put stream # in BX
- mov CX,word ptr dtabws ; get # bytes in full record
- mov SI,DX ; point to beginning of buffer
- int dos
- mov BX,word ptr REM ; restore the CRC remainder
- cmp CX,AX ; see if full record returned
- jz readit ; if so, process it
- or AX,AX
- jz short finish ; if 0, its eof
- mov CX,word ptr dtabps ; else, get # bytes in partial sector
- cmp AX,CX ; see if >= partial sector
- jae readit ; if so, process it
- mov DI,DX ;
- add DI,AX ; point DI past last byte returned
- push CX
- sub CX,AX
- xor AL,AL ; put null into AL
- rep stosb ; clear till boundary
- pop CX
-
- ; Fred Gutman's CRC generator from EDN, June 5, 1979, page 84
- ; optimized for the 8086 by Howard Vigorita
- ;
- readit:
- test BH,128 ; Q-bit mask accumulated crc
- lahf ; save status flags in AH
- shl BX,1 ; double old crc
- lodsb ; AL = byte ptr [SI++]
- add BL,AL ; add in new char
- sahf ; restore the flags from AH
- jz readit_1 ; skip mask if Q-bit was zero
- xor BX,0A097h ; CCIT CRC polynomial mask bytes
- readit_1:
- loop readit ; go read more characters
- jmp short filldta ; if none left, refill the dta
-
- FINISH:
- or AL,AL ;Normal end of file?
- jz FINISH1 ;Yes
- call closer2
- jmp FILERR ;No, it was a read error
-
- FINISH1:
- mov AL,Byte Ptr REM+1 ; Get top byte of CRC
- call HEXO ; Display it
- mov AL,' ' ; space between CRC bytes
- call TYPER
- mov AL,Byte Ptr REM ; Get bottom byte of CRC
- call HEXO ; Display it
- call closer2 ; close file we crck'd
- xor AL,AL ; ret with Z set to tell
- ret ; caller all went well
- ;
- FILERR:
- mov DX,offset READERR
- call DISPLAY
- xor AL,AL
- inc AL
- ret
- ;
- CLOSER:
- mov DX,offset fcb
- mov AH,CLOSE
- int dos
- ret
-
- closer2:
- mov BX,word ptr infileh
- mov AH,clostr
- int dos
- ret
-
- ; output ascii hex of the byte in AL
- ;
- HEXO:
- lahf ;SAVE FOR RIGHT DIGIT
- xchg AL,AH
- push AX
- xchg AL,AH
- RCR AL,1 ;RIGHT..
- RCR AL,1 ;..JUSTIFY..
- RCR AL,1 ;..LEFT..
- RCR AL,1 ;..DIGIT..
- call NIBBL ;PRINT LEFT DIGIT
- pop AX ;RESTORE RIGHT
- xchg AL,AH
-
- NIBBL:
- and AL,0FH ;ISOLATE DIGIT
- cmp AL,10 ;IS IS <10?
- jb NOTALPHA ;YES, NOT ALPHA
- add AL,7 ;add ALPHA BIAS
-
- NOTALPHA:
- add AL,'0' ;MAKE PRINTABLE
- jmp short TYPER ;PRINT IT, THEN RETURN
-
- ; substitute for inline print routine
- ; prints null terminated strings
- ; expects string address in [DX]
- ;
- display:
- mov BX,DX
- dspl_1: mov AL,byte ptr [BX] ; get char
- call typer ; output it
- inc BX ; point to next
- mov AL,byte ptr [BX] ; test
- or AL,AL ; ..for end
- jnz dspl_1
- ret ; ret to caller
-
- ; send carriage return, line feed to output
- ;
- crlf: mov AL,cr ; carriage return
- call typer
- mov AL,lf ; line feed, fall into 'type'
-
- ; send character in AL register to output
- ;
- typer:
- and AL,7Fh ; strip parity bit
- mov DL,AL
- push DX
- call wrfile ; write to file if requested
- pop DX
- mov AH,wrcon ; send character to console
- int dos
- ret
-
-
- wrfile:
- mov AL,Byte Ptr FFLAG
- cmp AL,'F' ;Write to file?
- jz wrf_2
- ret ;No
-
- wrf_2:
- mov AL,DL ;Yes
- push CX
- push BX
- call PUTCRCFILE
- pop BX
- pop CX
- ret
-
-
- ;Multi-file access subroutine. Allows processing
- ;of multiple files (i.e. *.ASM) from disk. This
- ;routine builds the proper name in the FCB each
- ;time it is called. Carry is set if no more names
- ;can be found.
- ;
- mfname: ; init dma addr and fcb
- mov AH,setdta
- mov DX,offset dta
- int dos
- xor AL,AL
- mov byte ptr fcbext,AL
- mov byte ptr fcbrno,AL
-
- ; if first time
- ;
- mov AL,byte ptr mfflg1
- or AL,AL
- jz mfn01
-
- ; save the requested name
- ;
- mov SI,offset fcb
- mov DI,offset mfreq
- mov CX,6
- rep movsw
- mov AL,byte ptr fcb
- mov byte ptr mfcur,AL ; save disk in curr fcb
-
- ; srchf requested name
- ;
- ; mov SI,offset mfreq
- ; mov DI,offset fcb
- ; mov CX,6
- ; rep movsw
- mov AH,srchf
- mov DX,offset fcb
- int dos
-
- ; else
- ;
- jmp short mfn02
- mfn01: ; srchf current name
- mov SI,offset mfcur
- mov DI,offset fcb
- mov CX,6
- rep movsw
- mov AH,srchf
- mov DX,offset fcb
- int dos
-
- ; srchn requested name
- ;
- mov SI,offset mfreq
- mov DI,offset fcb
- mov CX,6
- rep movsw
- mov AH,srchn
- mov DX,offset fcb
- int dos
-
- ; endif
- ;
- mfn02: ; return carry if not found
- inc AL
- STC
- jnz mfn03
- ret
-
- ; move name found to current name
- ;
- mfn03:
- mov SI,offset dta+1 ; place where MSDOS puts name
- push SI ; save name pointer
- mov DI,offset mfcur+1
- mov CX,11
- rep movsb
-
- ; move name found to fcb
- ;
- pop SI
- mov DI,offset fcb+1
- mov CX, 11
- rep movsb
-
- ; setup fcb
- ;
- xor AL,AL
- mov byte ptr fcbext,AL
- mov byte ptr fcbrno,AL
- mov byte ptr mfflg1,AL ; turn off 1st time sw
- ret
-
-
- ; test for $$$ filetype
- ;
- TSTBAD:
- call TESTIT ;Check first one for $
- jz TSTBAD1
- ret
-
- TSTBAD1:
- call TESTIT ;Check second on
- jz TESTIT
- ret
-
- TESTIT: ;Fall through to test third
- mov AL,byte ptr [BX]
- and AL,07Fh
- cmp AL,'$'
- lahf
- inc BX
- sahf
- ret
-
- ABEXT2:
- mov AL,Byte Ptr FFLAG
- cmp AL,'F' ;Writing to file?
- jnz ABEXT3 ;No
- ABEXT2A: ;Close incomplete file
- mov AL,eof
- call putcrcfile
- mov AH,clostr ; Close stream
- mov BX,word ptr crcouth ; CRCKLIST.$$$ stream number
- int dos
- jnc abext2C ; continue if carry not set
- mov AH,print ; else, print error message
- mov DX,offset abtext
- int dos
- ABEXT2C:
- mov AH,deldir
- mov DX,offset crcoutz
- int dos
- ABEXT3:
- mov DX,offset ABORT
- SIGNOFF:
- mov AH,print
- int dos
- mov AL,Byte Ptr MATCHFLG
- or AL,AL
- jz EXIT
- xor AL,AL
- mov Byte Ptr FFLAG,AL
- call CRLF
- mov DX,offset CRCMATCH
- call DISPLAY
- mov AL,Byte Ptr MATCHNO
- call DECIMAL
- mov AL,Byte Ptr NOMATCH
- or AL,AL
- jz PARSE
- call CRLF
- mov DX,offset CRCNOMATCH
- call DISPLAY
- mov AL,Byte Ptr NOMATCH
- call DECIMAL
- PARSE:
- mov AL,Byte Ptr FAILED
- or AL,AL
- jz NOTFOUND
- call CRLF
- mov DX,offset BADPARSE
- call DISPLAY
- mov AL,Byte Ptr FAILED
- call DECIMAL
- NOTFOUND:
- mov AL,Byte Ptr FILES
- or AL,AL
- jz EXIT
- call CRLF
- mov DX,offset QTYNOFIND
- call DISPLAY
- mov AL,Byte Ptr FILES
- call DECIMAL
-
- ; exit, via system terminate process function
- ;
- exit: mov AH, TrmProc ; return to DOS
- int dos
-
- ;
- DECIMAL:
- mov DL,0
- mov CH,064H
- call DEC1
- mov CH,10
- call DEC1
- add AL,'0'
- jmp TYPER
- ;
- DEC1:
- mov CL,0FFH
- DEC2:
- inc CL
- sub AL,CH
- jnb DEC2
- add AL,CH
- mov DH,AL
- mov AL,CL
- or AL,DL
- jz DEC3
- or AL,'0'
- call TYPER
- mov DL,'0'
- DEC3:
- mov AL,DH
- ret
-
- code ENDS
-
-
- ; stack location
- ; --------------
- ;
- a_stack SEGMENT PARA STACK
-
- db 100h dup (?)
-
- a_stack ENDS
-
-
- END crck